package cn.ihrm.sass.service;


import cn.common.ResultCode;
import cn.exception.CommonException;
import cn.ihrm.sass.dao.PermissionApiDao;
import cn.ihrm.sass.dao.PermissionDao;
import cn.ihrm.sass.dao.PermissionMenuDao;
import cn.ihrm.sass.dao.PermissionPointDao;
import cn.ihrm.sass.entity.system.Permission;
import cn.ihrm.sass.entity.system.PermissionApi;
import cn.ihrm.sass.entity.system.PermissionMenu;
import cn.ihrm.sass.entity.system.PermissionPoint;
import cn.service.BaseService;
import cn.utils.BeanMapUtils;
import cn.utils.IdWorker;
import cn.utils.PermissionConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Transactional //事务支持
public class PermissionService extends BaseService {
    @Autowired
    private PermissionDao permissionDao;

    @Autowired
    private PermissionMenuDao permissionMenuDao;

    @Autowired
    private PermissionApiDao permissionApiDao;

    @Autowired
    private PermissionPointDao permissionPointDao;

    @Autowired
    private IdWorker idWorker;

    /**
     * 保存用户
     * 1.配置idwork到工程
     * 2.在service中注入idwork
     * 3.通过idwork生成id
     * 4.保存企业
     */
    public void add(Map<String, Object> map) throws Exception {
        //通过map构建权限对象
        String id = idWorker.nextId() + "";
        Permission permission = BeanMapUtils.mapToBean(map, Permission.class);
        permission.setId(id);
        //根据类型构造不同的资源对象，（菜单，按钮，API）
        int type = permission.getType();
        // 进行判断
        switch (type) {
            case PermissionConstants.PY_MENU:
                PermissionMenu permissionMenu = BeanMapUtils.mapToBean(map, PermissionMenu.class);
                permissionMenu.setId(id);

                // 进行菜单权限 保存
                permissionMenuDao.save(permissionMenu);
                break;
            case PermissionConstants.PY_API:
                PermissionApi permissionApi = BeanMapUtils.mapToBean(map, PermissionApi.class);
                permissionApi.setId(id);

                permissionApiDao.save(permissionApi);
                break;
            case PermissionConstants.PY_POINT:
                PermissionPoint permissionPoint = BeanMapUtils.mapToBean(map, PermissionPoint.class);
                permissionPoint.setId(id);

                permissionPointDao.save(permissionPoint);
                break;
            default:
                throw new CommonException(ResultCode.FAIL);
        }
        // 进行保存 权限
        permissionDao.save(permission);
    }

    /**
     * 更新用户
     * 1.参数：Permission
     * 2.根据id查询企业对象
     * 3.设置需要修改的属性
     * 4.调用dao完成更新
     */
    public void update(Map<String, Object> map) throws Exception {
        //把map集合 转为 对象
        Permission permission = BeanMapUtils.mapToBean(map, Permission.class);
        // 通过传递的权限id查询权限
        Permission temp = permissionDao.findById(permission.getId()).get();

        // 更新相关权限
        temp.setName(permission.getName());
        temp.setCode(permission.getCode());
        temp.setDescription(permission.getDescription());
        temp.setEnVisible(permission.getEnVisible());
        //根据类型构造不同的资源
        //根据类型构造不同的资源对象，（菜单，按钮，API）
        int type = permission.getType();
        // 进行判断
        switch (type) {
            case PermissionConstants.PY_MENU:
                PermissionMenu permissionMenu = BeanMapUtils.mapToBean(map, PermissionMenu.class);
                // 应该也进行查询后再修改

                permissionMenu.setId(permission.getId());

                // 进行菜单权限 保存
                permissionMenuDao.save(permissionMenu);
                break;
            case PermissionConstants.PY_API:
                PermissionApi permissionApi = BeanMapUtils.mapToBean(map, PermissionApi.class);
                permissionApi.setId(permission.getId());

                permissionApiDao.save(permissionApi);
                break;
            case PermissionConstants.PY_POINT:
                PermissionPoint permissionPoint = BeanMapUtils.mapToBean(map, PermissionPoint.class);
                permissionPoint.setId(permission.getId());

                permissionPointDao.save(permissionPoint);
                break;
            default:
                throw new CommonException(ResultCode.FAIL);
        }
        //查询不同的的资源设置修改的属性


        permissionDao.save(temp);
    }


    /**
     * 删除用户
     */
    public void deleteById(String id) throws CommonException {

        Permission temp = permissionDao.findById(id).get();

        //根据类型构造不同的资源对象，（菜单，按钮，API）
        int type = temp.getType();
        // 进行判断
        switch (type) {
            case PermissionConstants.PY_MENU:
                permissionMenuDao.deleteById(id);
                break;
            case PermissionConstants.PY_API:
                permissionApiDao.deleteById(id);
                break;
            case PermissionConstants.PY_POINT:
                permissionPointDao.deleteById(id);
                break;
            default:
                throw new CommonException(ResultCode.FAIL);
        }
        //删除
        permissionDao.deleteById(id);
    }

    /**
     * 根据id查询用户
     */
    public Map<String, Object> findById(String id) throws CommonException {

        //Map<String,Object> map = new HashMap<>();
        // 根据id查询 权限
        Permission permission = permissionDao.findById(id).get();

        //PermissionMenu permissionMenu = permissionMenuDao.findById(id).get();
        int type = permission.getType();

        Object object = null;
        if (type == PermissionConstants.PY_MENU) {
            object = permissionMenuDao.findById(id).get();
        } else if (type == PermissionConstants.PY_API) {
            object = permissionApiDao.findById(id).get();
        } else if (type == PermissionConstants.PY_POINT) {
            object = permissionPointDao.findById(id).get();
        } else {
            throw new CommonException(ResultCode.FAIL);
        }

        Map<String, Object> map = BeanMapUtils.beanToMap(object);
        map.put("name", permission.getName());
        map.put("type", permission.getType());
        map.put("code", permission.getCode());
        map.put("description", permission.getDescription());
        map.put("pid", permission.getPid());
        map.put("enVisible", permission.getEnVisible());

        return map;
    }

    /**
     * 查询所有用户列表
     * 参数：
     * hasDept:
     * departmentId:
     * companyId:
     * 分页查询
     */
    public List<Permission> findAll(Map<String, Object> map) {
        // 查询条件
        Specification<Permission> spec = new Specification<Permission>() {
            /**
             * 动态拼接查询条件
             * @param root
             * @param query
             * @param cb
             * @return
             */
            @Override
            public Predicate toPredicate(Root<Permission> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<>();

                //判断
                // 根据pid 查询
                if (StringUtils.isEmpty(map.get("pid"))) {
                    list.add(cb.equal(root.get("pid").as(String.class), (String) map.get("pid")));
                }
                // 根据 enVisible查询
                if (StringUtils.isEmpty(map.get("enVisible"))) {
                    list.add(cb.equal(root.get("enVisible").as(String.class), (String) map.get("enVisible")));
                }

                //根据 类型查询
                if (StringUtils.isEmpty(map.get("type"))) {
                    String ty = (String) map.get("type");
                    CriteriaBuilder.In<Object> in = cb.in(root.get("type"));
                    if ("0".equals(ty)) {
                        in.value(1).value(2);
                    } else {
                        in.value(Integer.parseInt(ty));
                    }
                }

                // 拼接
                return cb.and(list.toArray(new Predicate[list.size()]));
            }
        };


        //return permissionDao.
        return permissionDao.findAll(spec);
    }
}
